package org.example.express.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.example.config.utils.SmsUtils;
import org.example.express.mapper.ExpressAccountMapper;
import org.example.express.mapper.ExpressAuthMapper;
import org.example.express.mapper.ExpressDetialMapper;
import org.example.express.mapper.ExpressListMapper;
import org.example.express.service.ExpressListService;
import org.example.model.common.Result;
import org.example.model.domain.express.ExpressAccount;
import org.example.model.domain.express.ExpressAuth;
import org.example.model.domain.express.ExpressDetial;
import org.example.model.domain.express.ExpressList;
import org.example.model.vo.login.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ExpressListServiceImpl implements ExpressListService {
    @Autowired
    private ExpressListMapper expressListMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ExpressDetialMapper expressDetialMapper;
    @Autowired
    private ExpressAccountMapper expressAccountMapper;
    @Autowired
    ExpressAuthMapper expressAuthMapper;
    /*登录注册接口*/


    /**
     * 发送验证码至指定手机号
     * 本方法用于生成一个六位数的验证码，并通过短信发送至指定的手机号码同时将验证码存储在Redis中，以备后续验证使用
     *
     * @param phone 接收验证码的手机号码
     * @return 操作结果，包含状态码和消息
     */
    @Override
    public Result vc(String phone) {
        try {
            // 生成六位数的随机验证码
            int c = RandomUtil.randomInt(100000, 1000000);
            // 使用SmsUtils发送验证码至指定手机号
            SmsUtils.sendSms(phone, Integer.toString(c));
            // 记录日志，输出验证码信息
            log.info("验证码为：" + c);
            // 将验证码存储到Redis中，使用手机号作为key，验证码作为value
            redisTemplate.opsForValue().set(phone, c);
            // 设置Redis中验证码的过期时间为5分钟
            redisTemplate.expire(phone, 60 * 5, java.util.concurrent.TimeUnit.SECONDS);
            // 返回发送成功的结果
            return Result.build(200, "发送成功");
        } catch (Exception e) {
            // 异常处理：打印异常栈并返回发送失败的结果
            e.printStackTrace();
            return Result.build(500, "发送失败");
        }
    }

    /*修改密码*/
    @Override
    public Result userPasswordUpdate(LoginVo loginVo) {
        try {
            expressListMapper.userPasswordUpdate(loginVo);
            ExpressList expressList = expressListMapper.selectByPhone(loginVo.getAccount());
            return Result.build(200, "修改成功", expressList);
        } catch (Exception e) {
            return Result.build(500, "修改失败");
        }

    }


    @Override
    public Result getUserInfoLogin(String registerIp) {
        if (isEmpty(registerIp)) {
            return Result.build(500, "用户信息获取失败");
        } else {
            ExpressList expressList = expressListMapper.selectByRegisterIp(Long.valueOf(registerIp));
            if (isEmpty(expressList)) {
                return Result.build(500, "用户信息获取失败");
            }
            return Result.build(200, "用户信息获取成功", expressList);
        }
    }


    //    @Override
    public Result getUserInfoAuth(Long registerIp) {
        List<ExpressAuth> expressAuth = expressAuthMapper.selectById(registerIp);
        if (isEmpty(expressAuth)) {
            return Result.build(500, "用户信息获取失败");
        } else {
            return Result.build(200, "用户信息获取成功", expressAuth);
        }
    }


    // 账号密码登录方法
    public Result<ExpressList> loginAPd(LoginVo loginVo) {
        boolean validPhoneNumber = isValidPhoneNumber(loginVo.getAccount());
        // 判断输入是否为有效的手机号码
        if (validPhoneNumber) {
            ExpressList expressList = expressListMapper.selectByPhone(loginVo.getAccount());
            // 根据手机号码查询用户信息
            if (expressList == null) {
                // 用户不存在，返回错误信息
                return Result.build(500, "用户不存在");
            }
            if (expressList.getPassword().equals(loginVo.getPassword())) {
                // 密码正确，将用户信息存入 Redis，并返回登录成功信息和用户信息
                setRedis(expressList);
                return Result.build(200, "登录成功", expressList);
            }
        } else {
            ExpressList expressListByEmail = expressListMapper.selectByEmail(loginVo.getAccount());
            // 根据邮箱查询用户信息
            if (expressListByEmail!= null) {
                if (expressListByEmail.getPassword().equals(loginVo.getPassword())) {
                    // 密码正确，将用户信息存入 Redis，并返回登录成功信息和用户信息
                    setRedis(expressListByEmail);
                    return Result.build(200, "登录成功", expressListByEmail);
                }
            } else {
                // 用户不存在，返回错误信息
                return Result.build(500, "用户不存在");
            }
        }
        return null;
    }

    //手机号验证码登录注册
    @Override
    @Transactional
    public Result<ExpressList> loginPVc(LoginVo loginVo) {
        // 记录日志，打印手机号
        log.info("手机号：{}", loginVo.getAccount());

        // 检查手机号是否为空
        if (StringUtils.isEmpty(loginVo.getAccount())) {
            return Result.build(500, "手机号不能为空");
        }

        // 检查验证码是否为空
        if (StringUtils.isEmpty(loginVo.getCode())) {
            return Result.build(500, "验证码不能为空");
        }

        // 检查验证码是否过期
        if (vcIsExpired(loginVo.getAccount())) {
            return Result.build(500, "验证码已过期");
        }

        // 根据手机号查询用户是否存在
        ExpressList existingUser = expressListMapper.selectByPhone(loginVo.getAccount());
        if (isEmpty(existingUser)) {
            // 用户不存在，进行注册流程
            Long registerIp = System.currentTimeMillis();
            ExpressList expressList = new ExpressList();
            expressList.setPhone(loginVo.getAccount());
            expressList.setRegisterIp(registerIp);
            expressList.setRegisterType(1);
            expressList.setAccount(loginVo.getAccount());
            expressList.setAreaCode(loginVo.getAreaCode());
            expressList.setIsVip(1);
            expressList.setLoginDate(new Date());
            expressListMapper.insertExpressList(expressList);

            ExpressAccount expressAccount = new ExpressAccount();
            expressAccount.setRegisterIp(String.valueOf(registerIp));
            expressAccount.setRecentLoginTime(new Date());
            expressAccount.setCreationTime(new Date());
            expressAccount.setPhone(loginVo.getAccount());
            expressAccount.setType(1);
            expressAccountMapper.insert(expressAccount);

            ExpressDetial expressDetial = new ExpressDetial();
            expressDetial.setRegisterIp(registerIp);
            expressDetial.setStatus(1);
            expressDetialMapper.insertExpressDetial(expressDetial);

            ExpressList registeredUser = expressListMapper.selectByRegisterIp(registerIp);
            if (isEmpty(registeredUser)) {
                return Result.build(500, "用户不存在");
            } else {
                // 将注册后的用户信息存入 Redis
                setRedis(registeredUser);
                // 删除验证码
                deleteVc(loginVo.getAccount());
                return Result.build(200, "注册成功", registeredUser);
            }
        } else {
            // 用户已存在，进行登录流程
            String vcRedis = vcRedis(loginVo.getAccount());
            if (vcRedis.equals(loginVo.getCode())) {
                ExpressList loggedInUser = expressListMapper.selectByPhone(loginVo.getAccount());
                // 删除验证码
                deleteVc(loginVo.getAccount());
                // 将登录后的用户信息存入 Redis
                setRedis(loggedInUser);
                return Result.build(200, "登录成功", loggedInUser);
            } else {
                return Result.build(500, "验证码错误");
            }
        }
    }

    /* 删除 Redis 中的验证码 */
    public void deleteVc(String phone) {
        redisTemplate.delete(phone);
    }

    /* 从 redis 中提取验证码 */
    public String vcRedis(String phone) {
        Object o = redisTemplate.opsForValue().get(phone);
        if (o != null) {
            return o.toString();
        }
        return null;
    }

    /* 判断验证码是否过期 */
    public boolean vcIsExpired(String phone) {
        String vcRedis = vcRedis(phone);
        return null == vcRedis;
    }

    /* 将用户信息存入 redis */
    public void setRedis(ExpressList expressList) {
        String key = "COURIER:EXPRESS:LOGIN" + expressList.getRegisterIp();
        redisTemplate.opsForValue().set(key, expressList);
        //设置过期时间30天
        redisTemplate.expire(key, 30, TimeUnit.DAYS);
    }

    /*判断手机号*/
    public static boolean isValidPhoneNumber(String phoneNumber) {
        String regex = "^1[3-9]\\d{9}$";
        return phoneNumber.matches(regex);
    }

    /* 判断对象是否为空，内容也为空 */
    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof String) {
            return StringUtils.isEmpty((String) obj);
        }
        return false;
    }


    /*判断实名状态*/
    public Boolean isRealName(String registerIp) {
        String key = "COURIER:EXPRESS:LOGIN" + registerIp;
        ExpressList expressList = (ExpressList) redisTemplate.opsForValue().get(key);
        if (expressList != null) {
            return expressList.getRealNameStatus() == 1;
        } else {
            return false;
        }
    }


}
